﻿#region License

// Copyright 2007-2008 Rory Plaire (codekaizen@gmail.com)
/*
 * This license governs use of the accompanying software. If you use the software, you
 * accept this license. If you do not accept the license, do not use the software.
 *
 * 1. Definitions
 * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
 * same meaning here as under U.S. copyright law.
 * A "contribution" is the original software, or any additions or changes to the software.
 * A "contributor" is any person that distributes its contribution under this license.
 * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
 *
 * 2. Grant of Rights
 * (A) Copyright Grant- Subject to the terms of this license, including the license conditions
 *     and limitations in section 3, each contributor grants you a non-exclusive, worldwide,
 *     royalty-free copyright license to reproduce its contribution, prepare derivative works
 *     of its contribution, and distribute its contribution or any derivative works that you create.
 * (B) Patent Grant- Subject to the terms of this license, including the license conditions and
 *     limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free
 *     license under its licensed patents to make, have made, use, sell, offer for sale, import,
 *     and/or otherwise dispose of its contribution in the software or derivative works of the
 *     contribution in the software.
 *
 * 3. Conditions and Limitations
 * (A) No Trademark License- This license does not grant you rights to use any contributors'
 *     name, logo, or trademarks.
 * (B) If you bring a patent claim against any contributor over patents that you claim are
 *     infringed by the software, your patent license from such contributor to the software
 *     ends automatically.
 * (C) If you distribute any portion of the software, you must retain all copyright, patent,
 *     trademark, and attribution notices that are present in the software.
 * (D) If you distribute any portion of the software in source code form, you may do so only under
 *     this license by including a complete copy of this license with your distribution. If you
 *     distribute any portion of the software in compiled or object code form, you may only do so
 *     under a license that complies with this license.
 * (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no
 *     express warranties, guarantees or conditions. You may have additional consumer rights under
 *     your local laws which this license cannot change. To the extent permitted under your local laws,
 *     the contributors exclude the implied warranties of merchantability, fitness for a particular
 *     purpose and non-infringement.
 *
 */

#endregion License

using System;

namespace NPack.Interfaces
{
    /// <summary>
    /// LU decomposition of a rectangular matrix.
    /// </summary>
    /// <typeparam name="TComponent">The type of the matrix element.</typeparam>
    /// <typeparam name="TMatrix">The type of the matrix.</typeparam>
    /// <remarks>
    /// <para>
    /// For an m-by-n Matrix{T} <c>A</c> with m &gt;= n, the LU decomposition is an m-by-n
    /// unit lower triangular Matrix{T} <c>L</c>, an n-by-n upper triangular Matrix{T} <c>U</c>,
    /// and a permutation vector <c>Pivot</c> of length m so that <c>Pivot * A = L * U</c>.
    /// If m &lt; n, then <c>L</c> is m-by-m and <c>U</c> is m-by-n.
    /// </para>
    /// <para>
    /// The LU decompostion with pivoting always exists, even if the Matrix{T} is
    /// singular, so the constructor will never fail.  The primary use of the
    /// LU decomposition is in the solution of square systems of simultaneous
    /// linear equations. There is no solution, or infinite solutions if
    /// <see cref="IsNonsingular"/> returns <see langword="false"/>.
    /// </para>
    /// </remarks>
    public interface ILUDecomposition<TComponent, TMatrix> : IFactorization<TComponent, TMatrix>
        where TComponent : struct, IEquatable<TComponent>, IComparable<TComponent>,
                           IComputable<TComponent>, IConvertible
        where TMatrix : IMatrix<TComponent, TMatrix>, IEquatable<TMatrix>,
                        IComparable<TMatrix>, IComputable<TMatrix>
    {
        /// <summary>
        /// Gets the determinant of the matrix.
        /// </summary>
        /// <exception cref="InvalidOperationException">Thrown if the matrix used to compute the factorization is non-square.</exception>
        Double Determinant { get; }

        /// <summary>
        /// Gets the lower triangular matrix <c>L</c> such that
        /// <c>A * <see cref="Pivot"/> = L * <see cref="U"/></c>.
        /// </summary>
        TMatrix L { get; }

        /// <summary>
        /// Gets true if the <typeparamref name="TMatrix"/> is non-singular,
        /// false if singular (non-invertible).
        /// </summary>
        Boolean IsNonsingular { get; }

        /// <summary>
        /// Gets the pivot permutation matrix.
        /// </summary>
        TMatrix Pivot { get; }

        /// <summary>
        /// Solves a set of equation systems of type <c>A * X = <paramref name="B"/></c>.
        /// </summary>
        /// <param name="B">
        /// Right hand side <typeparamref name="TMatrix"/> with as many rows as
        /// <c>A</c> and any number of columns.
        /// </param>
        /// <returns>
        /// <typeparamref name="TMatrix"/> <c>X</c> so that <c>L * U * X = <paramref name="B"/></c>.
        /// </returns>
        TMatrix Solve(TMatrix B);

        /// <summary>
        /// Gets the lower triangular matrix <c>L</c> such that
        /// <c>A * <see cref="Pivot"/> = <see cref="L"/> * U</c>.
        /// </summary>
        TMatrix U { get; }
    }
}